package com.flyox.game.fivetiger.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;

import com.flyox.game.fivetiger.control.FivetigerControl;

public class BroadCastServer implements Runnable {

	FivetigerControl control = null;

	public static final String QUERY_SERVERS = "1";
	public static final String RESPONSE = "2";
	public static final int PORT = 3722;
	public static final String BROAD_GROUP = "239.255.0.237";// 广播端口
	private boolean living = true;
	private boolean serverFlag = false;

	private InetAddress group;
	private MulticastSocket socket;
	private DatagramPacket packet;
	private String ip = "127.0.0.1";
	private byte[] sendData = new byte[20];
	private byte[] recData = new byte[20];

	private static BroadCastServer serverInstance = null;
	private static BroadCastServer clientInstance = null;

	private BroadCastServer(FivetigerControl control, boolean isServer) {
		this.control = control;
		serverFlag = isServer;
		try {
			ip = InetAddress.getLocalHost().getHostAddress();
			group = InetAddress.getByName(BROAD_GROUP);
			socket = new MulticastSocket(PORT);
			socket.joinGroup(group); // 加入组播组
			// socket.setTimeToLive(6);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	synchronized public static BroadCastServer getServerInstance(FivetigerControl control) {
		if (serverInstance == null) {
			serverInstance = new BroadCastServer(control, true);
			return serverInstance;
		} else {
			return serverInstance;
		}
	}

	synchronized public static BroadCastServer getClientInstance(FivetigerControl control) {
		if (clientInstance == null) {
			clientInstance = new BroadCastServer(control, false);
			return clientInstance;
		} else {
			return clientInstance;
		}
	}

	/**
	 * for receive msg
	 */
	public void run() {
		while (isLiving()) {
			try {
				recData = new byte[20];
				packet = new DatagramPacket(recData, recData.length, group, PORT);
				socket.receive(packet);
				String message = new String(packet.getData(), 0, packet.getLength()).trim();
				String[] response = message.split(":");
				if (QUERY_SERVERS.equals(response[0]) && isServerFlag()) {
					sendData = (RESPONSE + ":" + ip).getBytes();
					packet = new DatagramPacket(sendData, sendData.length, group, PORT);
					socket.send(packet);
				} else if (RESPONSE.equals(response[0])) {
					if (response[1] != null && !"".equals(response[1])) {
						control.getView().addIP(response[1]);
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
				close();
			}
		}
	}

	public void searchServer() {
		try {
			if (!isServerFlag()) {
				sendData = QUERY_SERVERS.getBytes();
				packet = new DatagramPacket(sendData, sendData.length, group, PORT);
				socket.send(packet);
				Timer timer = new Timer();
				TimerTask task = new TimerTask() {
					public void run() {
						close();
					}
				};
				timer.schedule(task, 50000);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void close() {
		setLiving(false);
		if (socket != null) {
			socket.close();
		}
	}

	public boolean isLiving() {
		return living;
	}

	public void setLiving(boolean living) {
		this.living = living;
	}

	public boolean isServerFlag() {
		return serverFlag;
	}

	public void setServerFlag(boolean serverFlag) {
		this.serverFlag = serverFlag;
	}

}
